package com.vincent.template.service.logic.impl;

import com.google.common.collect.Lists;
import com.vincent.template.commons.exception.Vct520Exception;
import com.vincent.template.domain.SysUriPo;
import com.vincent.template.dto.sys.uri.UriDto;
import com.vincent.template.repository.SysBindAuthUriRepository;
import com.vincent.template.repository.SysUriRepository;
import com.vincent.template.service.logic.UriService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Vincent Wang
 * @date 2021/3/25 19:23
 */
@Service
public class UriServiceImpl implements UriService {

    @Autowired
    private SysUriRepository uriRepository;
    @Autowired
    private SysBindAuthUriRepository bindAuthUriRepository;

    @Override
    public List<UriDto> findUris() {
        List<SysUriPo> uris = uriRepository.findAll();
        if (CollectionUtils.isEmpty(uris)) {
            return Lists.newArrayList();
        }
        return uris.stream().map(uri -> {
            UriDto uriDto = new UriDto();
            BeanUtils.copyProperties(uri, uriDto);
            return uriDto;
        }).collect(Collectors.toList());
    }

    @Override
    public UriDto findUriById(Long id) {
        SysUriPo uri = uriRepository.findById(id).orElse(null);
        if (uri == null) {
            return null;
        }
        UriDto uriDto = new UriDto();
        BeanUtils.copyProperties(uri, uriDto);
        return uriDto;
    }

    @Override
    public Long addUri(UriDto uriDto) {
        SysUriPo uri = uriRepository.findByPatternAndMode(uriDto.getPattern(), uriDto.getMode());
        String mode = Optional.ofNullable(uriDto.getMode()).orElse("ALL");
        Vct520Exception.throwIfTrue(uri != null,
                "该请求模式已经存在：" + mode + " " + uriDto.getPattern());
        uri = new SysUriPo();
        BeanUtils.copyProperties(uriDto, uri);
        return uriRepository.save(uri).getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUri(Long id, UriDto uriDto) {
        SysUriPo uri = uriRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(uri, "uri不存在");
        if (!Objects.equals(uri.getPattern(), uriDto.getPattern()) ||
                !Objects.equals(uri.getMode(), uriDto.getMode())) {
            String mode = Optional.ofNullable(uriDto.getMode()).orElse("ALL");
            Vct520Exception.throwIfTrue(uriRepository.findByPatternAndMode(uriDto.getPattern(), uriDto.getMode()) != null,
                    "该请求模式已经存在：" + mode + " " + uriDto.getPattern());
        }
        BeanUtils.copyProperties(uriDto, uri, "id");
        uriRepository.save(uri);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUri(Long id) {
        SysUriPo uri = uriRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(uri, "uri不存在");
        Vct520Exception.throwIfTrue(CollectionUtils.isNotEmpty(bindAuthUriRepository.findByUriId(id)),
                "有权限绑定了该uri，请先确认并解绑");
        uriRepository.delete(uri);
        return true;
    }

}
